package com.topscomm.file.service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import com.topscomm.basic.exception.ServiceException;
import com.topscomm.center.service.IFileManageService;
import com.topscomm.file.FileProperties;
import com.topscomm.file.FileSystemConst.FileUploadStateEnum;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;

import lombok.extern.slf4j.Slf4j;

/**
 * 文件合并链
 * 
 * @description:
 * @author: donghang
 * @date: 2020年8月20日下午2:48:18
 * @modify:
 */
@Slf4j
public class FileMergeFilter implements IFileProcessFilter {
	/**
	 * 
	 * @description:
	 * @author: donghang
	 * @date: 2020年8月21日上午11:34:03
	 * @modify:
	 */
	public FileMergeFilter() {

	}

	/**
	 * 进行文件块的合并处理
	 * 
	 * @description:
	 * @param paraMap
	 * @param dataProcessChain
	 * @return
	 * @author: donghang
	 * @date: 2020年8月20日下午2:52:32
	 * @modify:
	 */
	@Override
	public boolean doProcess(Map<String, Object> paraMap, IFileProcessChain dataProcessChain) {
		FileProperties fileProperties = (FileProperties) SpringUtil.getBean("fileProperties");
		String fileName = ConvertUtil.convertToString(paraMap.get("filename"));
		String identifier = ConvertUtil.convertToString(paraMap.get("identifier"));
		String sourceid = ConvertUtil.convertToString(paraMap.get("sourceid"));
		String sourcetype = ConvertUtil.convertToString(paraMap.get("sourcetype"));
		String location = ConvertUtil.convertToString(paraMap.get("foldername"));
		StringBuilder fileDirPath = new StringBuilder();
		StringBuilder filePath = new StringBuilder();
		// 合并后的文件
		String targetFile = filePath.append(fileProperties.getStorePath()).append("/").append(location).append("/")
				.append(fileName).toString();
		// 块文件夹
		String blockFolder = fileDirPath.append(fileProperties.getStorePath()).append("/").append(location)
				.append("/block").toString();
		Stream<Path> paths = null;
		try {
			File blockDir = new File(blockFolder);
			if (!blockDir.exists()) {
				dataProcessChain.doProcess(paraMap);
				return true;
			}
			// 修改文件状态
			IFileManageService fileManageService = (IFileManageService) SpringUtil.getBean("fileManageService");
			// 判断是否存在块文件，如果不存在则认为已经合并，继续链处理
			if (blockDir.listFiles().length == 0) {
				log.info("文件 ：" + targetFile + "先前已经合并完成");
				Map<String, Object> updataMap = new HashMap<String, Object>();
				updataMap.put("uploadstate", FileUploadStateEnum.Password);
				StringBufferProxy sql = new StringBufferProxy();
				sql.appendSingle(" 1=1 ");
				sql.appendSingle(" and identifier = '{0}' and sourceid='{1}' and sourcetype='{2}'", identifier,
						sourceid, sourcetype);
				fileManageService.updateByWhere(updataMap, sql.toString());
				dataProcessChain.doProcess(paraMap);
				return true;
			}

			paths = Files.list(Paths.get(blockFolder)).filter(path -> path.getFileName().toString().contains("block-"))
					.sorted((o1, o2) -> {
						String p1 = o1.getFileName().toString();
						String p2 = o2.getFileName().toString();
						int blockBeginIndex1 = p1.lastIndexOf("-");
						int suffixIndex1 = p1.lastIndexOf(".") == -1 ? p1.length() : p1.lastIndexOf(".");
						int blockBeginIndex2 = p2.lastIndexOf("-");
						int suffixIndex2 = p2.lastIndexOf(".") == -1 ? p2.length() : p2.lastIndexOf(".");
						return Integer.valueOf(p1.substring(blockBeginIndex1 + 1, suffixIndex1))
								.compareTo(Integer.valueOf(p2.substring(blockBeginIndex2 + 1, suffixIndex2)));

					});

			// 继续先前处理
			File file = new File(targetFile);
			if (!file.exists()) {
				Files.createFile(Paths.get(targetFile));
			}
			paths.forEach(path -> {
				// 以追加的形式写入文件
				try {
					log.info(path.getFileName().toString());
					Files.write(Paths.get(targetFile), Files.readAllBytes(path), StandardOpenOption.APPEND);
					// 合并后删除该块
					Files.delete(path);
				} catch (IOException e) {
					throw new ServiceException(e.getMessage());
				}
			});
			Map<String, Object> updataMap = new HashMap<String, Object>();
			updataMap.put("uploadstate", FileUploadStateEnum.Password);
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" 1=1 ");
			sql.appendSingle(" and identifier = '{0}' and sourceid='{1}' and sourcetype='{2}'", identifier, sourceid,
					sourcetype);
			fileManageService.updateByWhere(updataMap, sql.toString());
			log.info("合并文件 ：" + blockFolder + "完成");
			paraMap.put("OriginalFilePath", targetFile);
			if (dataProcessChain != null) {
				dataProcessChain.doProcess(paraMap);
			}
		} catch (Exception ex) {
			log.error("合并文件 ：" + blockFolder + "异常" + ex.getMessage());
			throw new ServiceException(ex.getMessage());
		} finally {
			if (paths != null) {
				paths.close();
			}
		}
		return true;
	}

}
